package fr.utbm.tx52.stamp.adapter;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import fr.utbm.tx52.stamp.logic.Constant;
import fr.utbm.tx52.stamp.logic.algorithm.SortAlgorithms;
import fr.utbm.tx52.stamp.logic.utils.DateUtil;
import fr.utbm.tx52.stamp.logic.utils.FileUtil;
import fr.utbm.tx52.stamp.ui.activity.Viewer;
import java.io.*;
import java.util.ArrayList;

/**
 * *
 *
 * Classe publique qui g�re la galerie horizontale permettant d'afficher des
 * vignettes avec des photos.
 *
 * @author Julien GONZALVES (julien.gonzalves@utbm.fr) Laurent RUBY
 * (laurent.ruby@utbm.fr)
 *
 */
public class ImageAdapter extends BaseAdapter
{

	//Attributs priv�s permettant de g�rer les �l�ments de la galerie
	private int galleryItemBackground;
	private Context imageAdapterContext;
	//Liste de fichiers permettant de contenir l'ensemble des images
	private ArrayList<File> files;
	private Listener listener;

	public ImageAdapter(Context context, Listener mode)
	{
		listener = mode;
		// R�cup�ration de la liste des images pr�sentes dans un dossier sp�cifique du p�riph�rique
		ArrayList<File> tmp = FileUtil.getSDCardContent();
		files = new ArrayList<File>();
		for (File file : tmp)
		{
			if (Constant.FILE_IMAGE_EXTENSION.contains(FileUtil.getExtension(file.getName())))
			{
				files.add(file);
			}
		}

		// Initialisation de l'objet permettant de r�aliser des tris
		SortAlgorithms sort = new SortAlgorithms(files);

		//On applique le tri en fonction de la valeur par d�faut
		if (Constant.DEFAULT_SORT)
		{
			// Tri croissant par date
			files = sort.sortByDate(true);
		}
		else
		{
			// Tri d�croissant par date
			files = sort.sortByDate(false);
		}

		//Mise � jour du contexte et utilisation du fichier XML pour initialiser la galerie
		imageAdapterContext = context;
		//TypedArray attr = imageAdapterContext.obtainStyledAttributes(R.styleable.XMLGallery);
		//galleryItemBackground = attr.getResourceId(R.styleable.XMLGallery_android_galleryItemBackground, 0);
		//attr.recycle(); 
	}

	/**
	 * *
	 * Fonction publique permettant de conna�tre le nombre de fichiers dans la
	 * galerie
	 *
	 * @return Un entier correspondant au nombre de fichiers dans la galerie
	 */
	public int getCount()
	{
		return files.size();
	}

	/**
	 * *
	 * Fonction publique permettant de r�cup�rer un �l�ment de la galerie �
	 * partir de sa position
	 *
	 * @param position La position de l'�l�ment que l'on souhaite r�cup�rer
	 * @return Un object contenant l'�l�ment � la position indiqu�e
	 */
	public Object getItem(int position)
	{
		return position;
	}

	/**
	 * *
	 * Fonction publique permettant de r�cup�rer la position d'un �l�ment de la
	 * galerie
	 *
	 * @param position La position de l'�l�ment � r�cup�rer
	 * @return Un entier contenant la position de l'�l�ment
	 */
	public long getItemId(int position)
	{
		return position;
	}

	/**
	 * *
	 * Proc�dure publique permettant de r�cup�rer la liste des fichiers
	 * actuellement dans la galerie
	 *
	 * @return La liste actuel des fichiers r�cup�r�s
	 */
	public ArrayList<File> getFiles()
	{
		return files;
	}

	public File getFile(int position)
	{
		return files.get(position);
	}

	/**
	 * *
	 * Proc�dure publique permettant de r�cup�rer et de redimensionner un objet
	 * de type "view" � partir de sa position dans la galerie
	 *
	 * @param position Position de l'�l�ment � r�cup�rer
	 */
	public View getView(final int position, View convertView, ViewGroup parent)
	{

		ImageView imageView = new ImageView(imageAdapterContext);
		Bitmap bMapScaled = getPicture(position);

		imageView.setImageBitmap(bMapScaled);
		// TODO Layout inflate
		imageView.setLayoutParams(new GridView.LayoutParams(160, 160));
		imageView.setAdjustViewBounds(true);
		imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
		imageView.setPadding(8, 8, 8, 8);
		listener.imageAdapter = this;
		imageView.setOnClickListener(listener);

		return imageView;
	}

	/**
	 * *
	 * Fonction publique permettant de r�cup�rer le nom de la photo � partir de
	 * son index
	 *
	 * @param index Position de la photo dont on souhaite connaitre le nom
	 * @return Le nom de la photo s'il est disponible.
	 */
	public String getPictureName(int index)
	{
		if (index >= 0 && index < getCount())
		{
			return files.get(index).getName();
		}
		return Constant.FILE_NAME_UNKNOWN;
	}

	/**
	 * *
	 * Fonction publique qui permet de r�cup�rer la date de la photo � partir de
	 * son index sous la forme d'une chaine de caract�res explicite
	 *
	 * @param index Position de la photo dont on souhaite connaitre la date de
	 * prise de vue
	 * @return La date de prise de vue de la photo si elle disponible.
	 */
	public String getPictureDate(int index)
	{
		if (index >= 0 && index < getCount())
		{
			return DateUtil.getCompleteDate(files.get(index));
		}
		return Constant.EXIF_FILE_DATE_UNKNOWN;
	}

	/**
	 * *
	 * Fonction publique permettant de r�cup�rer une image � partir de la liste
	 * des �l�ments sans lui appliquer de nouvelles dimensions
	 *
	 * @param index Position de la photo que l'on souhaite r�cup�rer
	 * @return Un objet Bitmap contenant la photo que l'on souhaite r�cup�rer
	 */
	public Bitmap getPicture(int index)
	{
		File currentPicture = files.get(index);
		//R�glage des param�tres pour �viter une erreur du type "OutOfMemoryError" lors de la convertion en Bitmap
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize = 8;
		Bitmap currentBitmap = null;
		try
		{
			currentBitmap = BitmapFactory.decodeStream(new FileInputStream(currentPicture), null, options);
		}
		catch (FileNotFoundException e)
		{
			Log.e(getClass().getSimpleName(), "", e);
		}
		return currentBitmap;
	}

	/**
	 * *
	 * Fonction publique permettant de r�cup�rer une image � partir de la liste
	 * des �l�ments disponibles en lui appliquant de nouvelles dimensions
	 *
	 * @param index Position de la photo que l'on souhaite redimensionner
	 * @param newWidth Correspond � la nouvelle taille que l'on souhaite
	 * appliquer � la photo
	 * @return La photo redimensionn�e dans un objet de type Bitmap
	 */
	private Bitmap getPictureResized(int index, int newWidth)
	{
		Bitmap currentBitmap = getPicture(index);
		//On r�alise un redimensionnement de la photo
		Bitmap currentBitmapResized = Bitmap.createScaledBitmap(currentBitmap, newWidth, newWidth, true);
		return currentBitmapResized;
	}

	/**
	 * *
	 * Fonction priv�e permettant de r�cup�rer une image � partir de la liste
	 * des �l�ments disponibles en lui appliquant les dimensions sp�cifiques
	 * pour la galerie
	 *
	 * @param position Position de la photo que l'on souhaite redimensionner pour
	 * la galerie
	 * @return La photo redimensionn�e dans un objet de type Bitmap
	 */
	private Bitmap getPictureResizedForGallery(int position)
	{
		return getPictureResized(position, Constant.GALLERY_WIDTH_PICTURE);
	}

	public enum Listener implements View.OnClickListener
	{

		LAUNCH,
		SELECT;
		public ImageAdapter imageAdapter;
		public int position;

		public void onLaunchClick(View v)
		{
			final Intent intent = new Intent(imageAdapter.imageAdapterContext, Viewer.class);
			intent.putExtra(Viewer.INDEX_KEY, position);
			imageAdapter.imageAdapterContext.startActivity(intent);
		}

		public void onSelectClick(View v)
		{
			((Viewer) imageAdapter.imageAdapterContext).select(position);
		}

		public void onClick(View v)
		{
			position = ((GridView) v.getParent()).indexOfChild(v);
			switch (this)
			{
				case LAUNCH:
					onLaunchClick(v);
					break;
				case SELECT:
					onSelectClick(v);
					break;
			}
		}
	}

	public File getAudioComment(int position)
	{
		return new File(FileUtil.getSoundPath(files.get(position).getAbsolutePath()));
	}

	public String getSender(int position)
	{
		String sender = "";
		File commentFile = new File(FileUtil.getCommentPath(files.get(position).getAbsolutePath()));
		try
		{
			FileInputStream fis = new FileInputStream(commentFile);
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
			sender = bufferedReader.readLine();
			bufferedReader.close();
			fis.close();
		}
		catch (FileNotFoundException ex)
		{
			Log.e(getClass().getSimpleName(), "", ex);
		}
		catch (IOException ex)
		{
			Log.e(getClass().getSimpleName(), "", ex);
		}
		return sender;
	}

	public String getComment(int position)
	{
		String comment = "";
		File commentFile = new File(FileUtil.getCommentPath(files.get(position).getAbsolutePath()));
		try
		{
			FileInputStream fis = new FileInputStream(commentFile);
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis));
			bufferedReader.readLine();
			String tmp;
			while ((tmp = bufferedReader.readLine()) != null)
			{
				comment += tmp;
			}
			bufferedReader.close();
			fis.close();
		}
		catch (FileNotFoundException ex)
		{
			Log.e(getClass().getSimpleName(), "", ex);
		}
		catch (IOException ex)
		{
			Log.e(getClass().getSimpleName(), "", ex);
		}
		return comment;
	}
}